#!/usr/bin/env python
import sys, os, re

def showdescription():
	print """This script performs any action to all computers
given in the machinefile.
Just feed it with a file of the type

computer1
computer2
...

and pass this file with the param -m <path to machinefile>.
(This file can be an mpi machinefile too). If no machinefile
was given the script looks in $HOME/machines for a file.

If you want the output formatted as a table then use -t.

Other params are passed to the machines except '-?' which results in
this text.

(C) Stefan Fruhner 2008
"""


def gethstr(size):
	"""Get human readable string"""
	if size > 1024*1024*1024:
		return '%.2fGB' % (size/1024./1024./1024.)
	elif size > 1024*1024:
		return '%.2fMB' % (size/1024./1024.)
	elif size > 1024:
		return '%.2fkB' % (size/1024.)
	else:
		return '%.2fB' % (size)

class machine:
	def __init__(self, name):
		self.name		= name
		self.cpus		= 1
		self.top		= None
		self.load		= None
		self.short		= None
		self.overload	= False
		self.freecpus	= 1

	def __cmp__(self, other):
		return cmp(self.load, other.load)

#MYLOCAL = os.environ.get('MYLOCAL')
MYLOCAL = os.environ.get('HOME')
machinefile= MYLOCAL+'/machines'

username = (os.popen('whoami').readlines())[0].strip()

arg	= sys.argv


showhelp		= ('-?' in arg) # detailed view of user's processes
savemachinefile	= ('-s' in arg) # save a machine file of mpi-type with free machines
tabular			= ('-t' in arg) # tabular results
if tabular: arg.remove('-t')
command = ""
#parsing params with value

if showhelp:
	showdescription()
	sys.exit(0)

l	= len(arg)
if l > 1:
	for i in range(l):
		if arg[i] == '-m' and i+1 < l: machinefile = arg[i+1]
		elif i>0 and arg[i-1]== '-m': continue
		elif i>0: command+= arg[i]+' '

#if not command:
	#print "No command given ... exit."
	#sys.exit(1)

if not os.path.exists(machinefile):
	showdescription()
	sys.exit(0)

print "Using machinefile",machinefile

f = open(machinefile, 'r')
lines = f.readlines()
f.close()

#### get all machines and their processor numbers from the file
machines = []
longest_name = 0
for l in lines:
	if l.lstrip().startswith('#'): continue # ignore comments
	if l.find(':') > -1:
		try:
			name 		= l[:l.find(':')]
		except:pass
		else:
			if name:
				machines.append(machine(name)) # save
				if len(name) > longest_name: longest_name = len(name)
	else:
		n = l.strip()
		if n: machines.append(machine(n)) # save
		if len(n) > longest_name: longest_name = len(n)

longest_name+=1

if not command:
	showdescription()
	sys.exit(1)
results={}
#print "visiting machines:"
for m in range(len(machines)):
	if not tabular:
		print '\n'+80*'-'
		print '%s@%s:~$ %s' %(username, machines[m].name, command)
	else:
		print '\r\t'+machines[m].name.ljust(longest_name,' '),
		sys.stdout.flush()
#	print 'answer from:',machines[m].name
	sshscript = 'ssh %s "%s"' % (machines[m].name, command)
	res = os.popen(sshscript).readlines()
	results[machines[m].name] = res
	if not tabular:
		for l in range(len(res)):
			res[l] = res[l].strip()
			print res[l]
#	print res

# print the results if tabular
if tabular:
	print '\r'
	sys.stdout.flush()
	#print '\r'+80*'-'
	for m in range(len(machines)):
		name	= machines[m].name
		res		= results[name]
		for l in range(len(res)):
			if l > 0: name = ''
			res[l] = res[l].strip()
			print "%s | %s" % (name.rjust(longest_name,' '), res[l])






